package com.example.qihuibao.network

import android.os.Handler
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import com.example.qihuibao.base.BaseActivity
import com.example.qihuibao.bean.BaseReqBean
import com.example.qihuibao.bean.BaseRspBean
import com.example.qihuibao.bean.ReqBean
import com.example.qihuibao.bean.Rspdata
import com.example.qihuibao.constant.Config
import com.example.qihuibao.constant.Global
import com.example.qihuibao.utils.DES3Util
import com.example.qihuibao.utils.extension.genericType
import com.google.gson.Gson
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
import kotlin.Exception

/**
 *     author : cwwei
 *     e-mail : 494545699@qq.com
 *     date   : 2022/08/18
 *     desc   : 封装retrofit统一请求
 */
object RetrofitModel {
    /**
     * post请求
     * url：除baseurl外的url，例如/app/xxx/。。。
     * json：JSONObject
     * result：请求的结果
     */
    inline fun <reified T>postJson(url:String, json: JSONObject, result: Result<T>) {
        val body = RequestBody.create(MediaType.parse("application/json"), json.toString())
        RetrofitManager.getInstance().httpApi.postJson(url, body)?.enqueue(object : Callback<ResponseBody>{
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                reqSuccess(response, result)
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                reqFailed(t, result)
            }
        })
    }

    /**
     * post请求
     * url：除baseurl外的url，例如/app/xxx/。。。
     * json：JSONObject(数据经过RSA加密)
     * result：请求的结果
     */
//    inline fun <reified T>postJson2(url:String, body: RequestBody, result: Result<T>) {
//        api.postJson2(Config.appCode, System.currentTimeMillis().toString(), url, body)?.enqueue(object : Callback<ResponseBody>{
//            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
//                reqSuccess(response, result)
//            }
//
//            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
//                reqFailed(t, result)
//            }
//        })
//    }

    /**
     * post请求
     * url：除baseurl外的url，例如/app/xxx/。。。
     * json：JSONObject(数据经过RSA加密)
     * result：请求的结果
     */
//    inline fun <reified T>postJson2NoRSA(url:String, json: JSONObject, result: Result<T>) {
//        val body = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), json.toString())
//        api.postJson2(Config.appCode, System.currentTimeMillis().toString(), url, body)?.enqueue(object : Callback<ResponseBody>{
//            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
//                reqSuccess(response, result)
//            }
//
//            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
//                reqFailed(t, result)
//            }
//        })
//    }

    /**
     * post请求
     * url：除baseurl外的url，例如/app/xxx/。。。
     * form：Map<String,String>
     * result：请求的结果
     */
    inline fun <reified T>postForm(url:String, form:SortedMap<String,Any>, result: Result<T>) {
        RetrofitManager.getInstance().httpApi.postForm(url, form)?.enqueue(object : Callback<ResponseBody>{
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                reqSuccess(response, result)
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                reqFailed(t, result)
            }
        })
    }

    //统一请求入口
    inline fun <K : BaseReqBean, reified T : BaseRspBean> requestEntry(req:K, default:T) : LiveData<T> {
        val data = MediatorLiveData<T>()

        val json = Global.gson.toJson(req)
//        LogUtil.e("req = $json")
        val reqdata = DES3Util.EncryptData(json, Global.CorpKey)
        val body = ReqBean(reqdata, Global.CorpID)//加密请求数据
        RetrofitManager.getInstance().httpApi.post(body)?.enqueue(object : Callback<ResponseBody>{
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                val rsp = response.body()?.string() ?: return
                val rspData = Global.gson.fromJson(rsp, Rspdata::class.java) ?: return
                val encryptData = rspData.repdata.replace("\n", "")//这是一个坑
                val realData = DES3Util.DecryptData(encryptData, Global.CorpKey)
//                LogUtil.e("rsp = $realData")
//                if (!Config.isStation) {
//                    //todo for test 转发给服务站来请求
//                    BaseActivity.socketService?.pushClientSendData(req.TranCode, "${Global.CLIENT_REQ_HEAD}${req.TranCode}###${Global.gson.toJson(req)}") { type, s ->
//                        val retData = DES3Util.DecryptData(s, Global.CorpKey)//解密响应数据
//                        if (retData.isNullOrEmpty()) {
//                            default.RetCode = "-1"
//                            default.RetMsg = "data is null or empty"
//                            data.postValue(default)
//                        }else {
//                            try {
//                                val retBean = parse<T>(retData)
//                                if (retBean != null) {
//                                    data.postValue(retBean)
//                                }else {
//                                    default.RetCode = "-1"
//                                    default.RetMsg = "json trans error"
//                                    data.postValue(default)
//                                }
//                            }catch (e:Exception) {
//                                default.RetCode = "-1"
//                                default.RetMsg = "${e.message}"
//                                data.postValue(default)
//                            }
//                        }
//                    }
//                    return
//                }
                try {
                    val bean = parse<T>(realData)
                    if (bean != null) {
                        data.value = bean
                    }else {
                        default.RetCode = "-1"
                        default.RetMsg = "json trans error"
                        data.value = default
                    }
                }catch (e:Exception) {
                    default.RetCode = "-1"
                    default.RetMsg = "${e.message}"
                    data.value = default
                }
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                if (!Config.isStation) {
                    //todo for test 转发给服务站来请求
                    BaseActivity.socketService?.pushReqToStation(req.TranCode, "${Global.CLIENT_REQ_HEAD}${req.TranCode}###${Global.gson.toJson(req)}") { type, s ->
                        val retData = DES3Util.DecryptData(s, Global.CorpKey)//解密响应数据
                        if (retData.isNullOrEmpty()) {
                            default.RetCode = "-1"
                            default.RetMsg = "data is null or empty"
                            data.value = default
                        }else {
                            try {
                                val retBean = parse<T>(retData)
                                if (retBean != null) {
                                    data.value = retBean
                                }else {
                                    default.RetCode = "-1"
                                    default.RetMsg = "json trans error"
                                    data.value = default
                                }
                            }catch (e:Exception) {
                                default.RetCode = "-1"
                                default.RetMsg = "${e.message}"
                                data.value = default
                            }
                        }
                    }
                }else {
                    var errorMsg = t.message?:"请求异常"
                    when {
                        errorMsg.toLowerCase(Locale.ROOT).contains("no address associated with hostname") -> errorMsg = "请检查网络"
                        errorMsg.toLowerCase(Locale.ROOT).contains("failed to connect") -> errorMsg = "网络/服务器异常"
                        errorMsg.toLowerCase(Locale.ROOT).contains("timeout") -> errorMsg = "请求超时"
                    }
                    default.RetCode = "-1"
                    default.RetMsg = errorMsg
                    data.value = default
                }
            }
        })

        return data
    }

    //统一请求入口2
    inline fun <K : BaseReqBean, reified T : BaseRspBean> requestEntry2(req:K, result: Result<T>) {
        if (!Config.isStation && (!Global.connectICBC || !Global.networkOk) && Global.connectStation) {//本地终端&连不上服务器&连上服务站
            //尝试转发给服务站来请求
            var received = false
            BaseActivity.socketService?.pushReqToStation(req.TranCode, "${Global.CLIENT_REQ_HEAD}${req.TranCode}###${Global.gson.toJson(req)}") { type, s ->
                received = true
                val retData = DES3Util.DecryptData(s, Global.CorpKey)//解密响应数据
                result.onSucced(parse<T>(retData))
            }
            Handler().postDelayed({ if (!received) { result.onFailed("服务站没回应") } }, 5000)
        }else {
            val reqData = DES3Util.EncryptData(Global.gson.toJson(req), Global.CorpKey)//加密请求数据
            RetrofitManager.getInstance().httpApi.post(ReqBean(reqData, Global.CorpID))?.enqueue(object : Callback<ResponseBody>{
                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    reqSuccess(response, result)
                }

                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    var errorMsg = t.message?:"请求异常"
                    when {
                        errorMsg.toLowerCase(Locale.ROOT).contains("no address associated with hostname") -> errorMsg = "请检查网络"
                        errorMsg.toLowerCase(Locale.ROOT).contains("failed to connect") -> errorMsg = "网络/服务器异常"
                        errorMsg.toLowerCase(Locale.ROOT).contains("timeout") -> errorMsg = "请求超时"
                    }
                    reqFailed(t, result)
                }
            })
        }
    }

    inline fun <reified T>getRequest(url:String, json: JSONObject, result: Result<T>) {
        val body = RequestBody.create(MediaType.parse("application/json"), json.toString())
        RetrofitManager.getInstance().httpApi.getRequest(url)?.enqueue(object : Callback<ResponseBody>{
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                reqSuccess(response, result)
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                reqFailed(t, result)
            }
        })
    }

    inline fun <reified T> reqSuccess(response: Response<ResponseBody>, result: Result<T>) {
//        var data = response.body()?.string()?:"数据异常"
//        if (data.contains("\\\"")) {//返回的json格式有问题时
//            data = data.replace("\\\"", "\"").replace("\"{", "{").replace("}\"", "}");
//        }
        try {
            val rspData = Global.gson.fromJson(response.body()?.string()?:"数据异常", Rspdata::class.java)//响应数据为json格式字符串，先转换
            if (rspData != null) {
                val encryptData = rspData.repdata.replace("\n", "")//这是一个坑
                val realData = DES3Util.DecryptData(encryptData, Global.CorpKey)//解密
                result.onSucced(parse<T>(realData))
            }else {
                result.onFailed("数据解析异常")
            }
        }catch (e:Exception) {
            result.onFailed(e.message?:"")
        }
    }

    fun <T> reqFailed(t: Throwable, result: Result<T>) {
        var errorMsg = t.message?:"请求异常"
        when {
            errorMsg.toLowerCase(Locale.ROOT).contains("no address associated with hostname") -> errorMsg = "请检查网络"
            errorMsg.toLowerCase(Locale.ROOT).contains("failed to connect") -> errorMsg = "网络/服务器异常"
            errorMsg.toLowerCase(Locale.ROOT).contains("timeout") -> errorMsg = "请求超时"
        }
        result.onFailed(errorMsg)
    }

    //使用内联函数可以把json数据转换为某个类实例
//    inline fun <reified T>parse(data: String):T = Gson().fromJson(data, T::class.java)
    inline fun <reified T>parse(data: String):T? = Gson().fromJson(data, genericType<T>())

    //结果回调
    interface Result<T> {
        fun onSucced(result: T?)
        fun onFailed(errMsg: String)
    }

}
